<!-- dt-table.vue -->
<template>
  <div>
    <dtSearchForm ref="dtSearchForm" :table-col="tableCol" :search="search"
                  v-on="$listeners" @update:search="()=>$emit('update:search',search)" />
    <div class="table-container table-fullscreen">
      <div class="table-opt-container">
        <template v-if="tableOpts.toolbarBtn">
          <el-button
            v-for="(value, index) in tableOpts.toolbarBtn"
            :key="index"
            v-permission="value.permission || []"
            :icon="value.icon ? value.icon : ''"
            :type="value.type"
            :disabled="value.disabled || false"
            :size="value.size || ''"
            v-bind="value.bind"
            @click="value.click && value.click()"
            v-on="value.listeners"
          >{{ value.label || '按钮' }}</el-button>
        </template>
        <slot name="toolbarBtn" />
        <div class="flex-1" />
        <dt-dialog-column v-show="$attrs['is-show-column'] != false" :columns="tableCol" v-bind="$attrs"
                          :table-ref="$refs.table" @queryTable="getList" />
      </div>
      <el-table
        ref="table"
        :data="tableData"
        style="width: 100%"
        :stripe="tableOpts.stripe || false"
        :border="tableOpts.border != false"
        :show-header="tableOpts.showHeader != false"
        :fit="tableOpts.fit != false"
        :highlight-current-row="tableOpts.highlightCurrentRow || false"
        :header-cell-style="{backgroundColor: '#f2f2f2'}"
        v-bind="tableOpts.bind || $attrs"
        :row-key="tableOpts.rowKey || $attrs['row-key'] || 'id'"
        @row-click="rowClick"
        @selection-change="handleSelectionChange"
        v-on="tableOpts.listeners || $listeners"
      >
        <template slot="empty">
          <svg-icon
            v-if="Boolean(this.$store.getters.dataText.trim())"
            icon-class="emptyTable"
            class="emptyImg"
          />
          <p>{{ $store.getters.dataText }}</p>
        </template>

        <!--表格第一列-->
        <el-table-column
          v-if="firstTableCol && firstTableCol.select != false"
          fixed="left"
          type="selection"
          :width="firstTableCol.width || 55"
          v-bind="firstTableCol.bind"
          :reserve-selection="firstTableCol.isPaging != false"
        />
        <el-table-column
          v-if="indexTableCol && indexTableCol.index != false"
          fixed="left"
          type="index"
          :label="indexTableCol.label || '序号'"
          :width="indexTableCol.width || 70"
          :align="indexTableCol.align || 'center'"
          :index="tableOpts.configPagination==='1'?(index)=>(paginationData.queryParams.pageNo - 1) * paginationData.queryParams.pageSize + index + 1:(index)=>index"
          v-bind="indexTableCol.bind"
        />
        <!-- :index="tableOpts.configPagination==='1'?(index)=>(paginationData.queryParams.pageNo - 1) * paginationData.queryParams.pageSize + index + 1:index" -->

        <!--表格其它列-->
        <template v-for="(value,index) in tableCol">
          <el-table-column
            v-if="value.show != false"
            :key="index"
            :prop="value.prop"
            :label="value.label"
            :sortable="value.sortable"
            :align="value.align || 'center'"
            :fixed="value.fixed"
            :show-overflow-tooltip="value.showOverflowTooltip != false"
            :width="value.width"
            v-bind="value.bind"
          >
            <template slot="header">
              {{ value.label }}{{ value.type }}
              <el-popover
                v-if="value.columnSearch || false"
                placement="bottom-start"
                width="400"
                :value="value.columnSearchVisible"
                trigger="click"
                @show="show(value)"
              >
                <div class="column-search-body">
                  <searchFormItem :item="value" :form-model="formModel" @searchSubmit="columnSearchComfirm(value)" />
                  <!-- <el-input v-model="value.columnSearchValue" :placeholder="value.label"  @keyup.enter.native="columnSearchComfirm(value)"></el-input> -->
                  <div class="column-search-handleBtn">
                    <el-button @click="columnSearchReset(value)">重置</el-button>
                    <el-button @click="columnSearchComfirm(value)">确定</el-button>
                  </div>
                </div>
                <span slot="reference" class="column-search-btn" @click.stop>
                  <svg-icon icon-class="column-search" />
                </span>
              </el-popover>
            </template>
            <template slot-scope="scope">
              <!--扩展dom-->
              <template v-if="value.render">
                <Table :key="`cus${index}`" :render="value.render" :param="scope.row" />
              </template>
              <!-- 自定义插槽 -->
              <template v-else-if="value.slotName">
                <slot :name="value.slotName" :param="scope.row" />
              </template>
              <template v-else>
                <!-- 字典 -->
                <template v-if="value.formatter && value.type == 'dict'">
                  <dt-dict-tag :options="value.formatter(scope.row,value)" :value="scope.row[value.prop]" />
                </template>
                <!-- 开关switch    -->
                <template v-else-if="value.type == 'switch'">
                  <el-switch
                    v-model="scope.row[value.prop]"
                    :disabled="(value.disabledChange && value.disabledChange(scope.row)) || false"
                    :active-value="value.activeValue || false"
                    :inactive-value="value.inactiveValue || false"
                    v-bind="value.elBind"
                    v-on="value.elListeners"
                    @change="value.switchChange(scope.row,value)"
                  />
                </template>
                <!-- 类型 -->
                <template v-else-if="value.formatter">
                  {{ value.formatter(scope.row, value)||'-' }}
                </template>
                <!-- 图片 -->
                <template v-else-if="value.type=='image' && value.getImgurl">
                  <el-image
                    :src="value.getImgurl(scope.row, value)"
                    style="width: 70px; height: 70px"
                    :style="value.style || {}"
                    v-bind="value.elBind"
                    :preview-src-list="value.previewSrcList ? value.previewSrcList(scope.row, value) : value.getImgurl(scope.row, value).split(',')"
                    v-on="value.elListeners"
                  />
                </template>

                <!-- 密码 -->
                <template v-else-if="value.type=='password'">
                  {{ scope.row[value.prop]?'***':'-' }}
                </template>
                <!-- 默认 -->
                <template v-else>
                  {{ scope.row[value.prop] ||'-' }}
                </template>
              </template>
            </template>
          </el-table-column>
        </template>
        <!--基础操作-->
        <el-table-column
          v-if="operatorBtn.length > 0"
          :fixed="operator.fixed || null"
          :align="operator.align || 'center'"
          v-bind="operator.bind "
          class-name="small-padding fixed-width"
          :width="operator.width || 100"
          label="操作"
        >
          <template slot-scope="scope">
            <el-button
              v-for="(value,index) in operatorBtn"
              :key="index"
              v-permission="value.permission || []"
              :size="value.size || 'small'"
              :icon="value.icon ? value.icon : ''"
              :type="value.type"
              :disabled="(value.disabledChange && value.disabledChange(scope.row)) || false"
              v-bind="value.bind"
              @click="value.click(scope.row, value,scope.$index)"
              v-on="value.listeners"
            >
              {{ value.text }}
            </el-button>
            <slot name="operatorBtn" :param="scope.row" />
          </template>
        </el-table-column>
      </el-table>
      <!--分页插件-->
      <dt-pagination
        v-show="paginationData.total>0&&tableOpts.configPagination==='1'"
        :total="paginationData.total"
        :page.sync="paginationData.queryParams.pageNo"
        :limit.sync="paginationData.queryParams.pageSize"
        @pagination="getList"
      />
    </div>
  </div>
</template>

<script>
// render函数
import Table from './table'
import searchFormItem from './searchFormItem.vue'

export default {
  name: 'DtTable',
  components: { Table, searchFormItem },
  props: {
    // 接口所需参数
    apiProps: {
      type: Object,
      default: () => {
        return {
          id: '123'
        }
      }
    },
    // 接口对象
    api: {
      type: Object,
      default: () => {
        return {}
      }
    },
    search: {
      type: Object,
      default: () => {}
    },
    tableOpts: {
      type: Object,
      require: true,
      default: () => ({
        toolbarBtn: [], // 操作行,
        bind: {},
        tableCol: [],
        listeners: {},
        configPagination: '1'
      })
    },
    /**
       * 表格头
       */
    // tableTitle: {
    //   type: Object,
    //   default: () => ({
    //     stripe: false,
    //     border: true,
    //     fit: true,
    //     highlightCurrentRow: false
    //   })
    // },
    /**
       * 表格第一列
       */
    // firstTableCol: {
    //   type: Object,
    //   default: (obj) => ({
    //     select: false,
    //     width: 55,
    //     type: 'selection'
    //   })
    // },
    /**
       * 表格序号列
       */
    // indexTableCol: {
    //   type: Object,
    //   default: () => ({
    //     index: true,
    //     width: 70,
    //     label: '序号'
    //   })
    // },
    /**
       * 表格列
       *    @param search 表单搜索
       *    @param clearable 是否可清空，默认可清空
       *    @param valueFormat 日期value的格式，默认格式yyyy-MM-dd
       *    @param format 日期展示的格式，默认格式yyyy-MM-dd
       *    @param pickerOptions 当前时间日期选择器, 同el-date-picker组件的配置项picker-options
       *    @param searchValue  搜索框添加默认值
       *    @param searchslot ture为父组件自定义搜索表单   插槽name为“prop+'Search'”
       *    @param type 表单搜索支持input、select、dict（字典表select）、date、datetimerange四种，其他类型请使用插槽searchslot自行定义
       *    @param dicData   type为select时，options选项值
       * [
       *   { prop:'date',label:'日期',width:200,search:true},
       *   { prop:'status',label:'状态',type:'switch',disabled:true,activeValue:true,inactiveValue:false, switchChange:(row,col)=>{}},   //开关类型
       *   { prop:'sex',label:'性别',type:'dict',formatter: () => {return this.dict.type.sex}}，  //字典类型
            { prop:'src',label:'图片',  getImgurl: (row, col, cellValue) => { return this.getImgurl(row)}, previewSrcList: (row, col, cellValue) => {return this.listImgUrl(row)}},  //图片类型
            { prop:'text',label:'函数', render: (h, params) => {return  this.render(h, params)}} // render类型
       * ]
       *
       */
    // tableCol: {
    //   type: Array,
    //   default: () => []
    // },
    /**
       * 表格数据
       */
    // tableData: {
    //   type: Array,
    //   default: () => []
    // },
    /**
       * 操作列
       *    @param text 文案
       *    @param size 大小
       *    @param permission 权限标识  []
       *    @param click 点击回调
       *
       *  { 'text': '详情',permission:[],size:'small',  click: (row, col, cellValue) => { return this.getInfo(row) } },
          { 'text': '删除', click: (row, col, cellValue) => { return this.delInfo(row) } },
          { 'text': '编辑', click: (row, col, cellValue) => { return this.editInfo(row) } }
       */
    // operator: {
    //   type: Array,
    //   default: () => []
    // },
    /**
       * 操作列配置
       */
    // operator: {
    //   type: Object,
    //   default: () => ({
    //     width: 100
    //   })
    // },
    // total: {
    //   type: Number,
    //   default: 0
    // },
    // page: {
    //   type: Number,
    //   default: 1
    // },
    // limit: {
    //   type: Number,
    //   default: 10
    // },
    // autoScroll: {
    //   type: Boolean,
    //   default: true
    // },
    /**
       * 分页参数
       */
    paginationData: {
      type: Object,
      default: () => ({
        total: 0,
        queryParams: {
          pageNo: 1,
          pageSize: 10

        }
      })
    }
  },
  data() {
    return {
      formModel: {}
    }
  },
  computed: {
    tableSearch() {
      return (this.tableCol || []).filter((item) => item.search)
    },
    toolbarBtn() {
      return this.tableOpts.toolbarBtn || {}
    },
    firstTableCol() {
      return this.tableOpts.firstTableCol || {}
    },
    indexTableCol() {
      return this.tableOpts.indexTableCol || {}
    },
    tableCol() {
      return this.tableOpts.tableCol || []
    },
    tableData() {
      return this.tableOpts.tableData || []
    },
    operator() {
      return this.tableOpts.operator || {}
    },
    operatorBtn() {
      return this.tableOpts.operator?.operatorBtn || []
    },
    currentPage: {
      get() {
        return this.page
      },
      set(val) {
        this.$emit('update:page', val)
      }
    },
    pageSize: {
      get() {
        return this.limit
      },
      set(val) {
        this.$emit('update:limit', val)
      }
    }
  },
  mounted() {
    window.addEventListener('resize', this.handleResize) // 处理错位问题
  },
  destroyed() {
    window.removeEventListener('resize', this.handleResize)
  },
  methods: {
    handleResize() {
      this.$nextTick(() => {
        this.$refs.table.doLayout()
      })
    },
    // 监听table选择框
    handleSelectionChange(selection) {
      // 调用父组件对应的方法 handleSelectionChange
      this.$emit('handleSelectionChange', selection)
    },
    getList() {
      this.$emit('pagination')
    },
    show(value) {
      // this.tableCol.map(item=>{
      //  this.hidePopOver(item)
      // })
      this.$set(value, 'columnSearchVisible', true)
    },
    columnSearchComfirm(value) {
      this.hidePopOver(value)
      this.searchEmit()
    },
    columnSearchReset(value) {
      this.formModel[value.prop] = ''
      this.hidePopOver(value)
      this.searchEmit()
    },
    hidePopOver(value) {
      value.columnSearchVisible = false
    },
    composeData(childFormModel) {
      const parentMole = this.formModel
      this.tableCol.forEach((item) => {
        if (!item.columnSearch && parentMole[item.prop]) {
          parentMole[item.prop] = ''
        }
      })
      const keys = Object.keys(childFormModel).concat(Object.keys(parentMole))
      const result = {}
      keys.forEach((item) => {
        result[item] = parentMole[item] || childFormModel[item]
      })
      return result
    },
    searchEmit() {
      this.$emit('searchChange', this.composeData(this.$refs.dtSearchForm ? this.$refs.dtSearchForm.formModel : {}))
    },
    // 取消/开启某一项是否选中
    toggleRowSelection(row, selected = false) {
      this.$refs['table'].toggleRowSelection(row, selected)
    },
    clearSelection() {
      this.$refs['table'].clearSelection()
    },
    setCurrentRow(row, selected = false) {
      this.$refs['table'].setCurrentRow(row, selected)
    },
    DtSearchReset() {
      this.$refs['dtSearchForm'].DtSearchReset(true)
    },
    rowClick(row, column) {
      if (this.firstTableCol.select === false) {
        this.$emit('radioChange', row)
      } else {
        // this.$refs['table'].toggleRowSelection(row)
        this.firstTableCol?.isRowClickSelect && this.$refs['table'].toggleRowSelection(row)
      }
    }
  }
}
</script>
  <style scoped lang="scss">
  .table-container{
    .table-opt-container{
      > .el-button{
        // margin-right: 10px;
      }
      > .el-dropdown{
        margin-left: 10px;
      }
    }
  }
  // ::v-deep .el-table{
  //   thead th:not(.is-hidden):last-child {
  //   right: -2px;
  // }
  //   .el-table__row td:not(.is-hidden):last-child {
  //     right: -1px;
  //   }

  // }
  // ::v-deep .el-table__fixed::before, .el-table__fixed-right::before {
  //   background-color: #D8D8D8;
  // }
  ::v-deep.el-table >.el-table__fixed-right {
    // height: 100% !important;
    // right: -1px;
    // border-right: 1px solid #D8D8D8;
  }
  ::v-deep.el-table >.el-table__fixed {
    // height: 100% !important;
    // left: -1px;
    // border-right: 1px solid #D8D8D8;
  }
  ::v-deep.el-table .el-table__row td:not(.is-hidden) {
    right: 1px;
  }
  ::v-deep .el-table{

    .column-search-btn{
      width: 20px;
      display: inline-block;
      cursor: pointer;
    }
    .column-search-body{

    }
  }
  .column-search-handleBtn{
    float: right;
    padding-top: 10px;
  }
  .emptyImg {
    width: 112px;
    height: 122px;
    margin: 80px 0 20px 0;
  }

  ::v-deep .el-table__empty-text {
    line-height: 0;
  }
  </style>

